package service

import (
	"errors"
	"fmt"
	"gitee.com/lanshiren/miniprogram/app/log"
	"gitee.com/lanshiren/miniprogram/app/model"
	"time"
)

// SaveActivity ...
func SaveActivity(vo *model.ActivityVO) error {
	acDo := model.ActivityDO{
		Title:                vo.Title,
		LeaderSay:            vo.LeaderSay,
		RouteDesc:            vo.RouteDesc,
		RoutePics:            vo.RoutePics,
		CollectionPlace:      vo.CollectionPlace,
		LeaderID:             vo.LeaderID,
		QrCode:               vo.QrCode,
		StartTime:            vo.StartTime,
		RegistrationDeadline: vo.RegistrationDeadline,
		Status:               vo.Status,
		CountLimit:           vo.CountLimit,
	}
	if err := model.CreateActivity(&acDo); err != nil {
		return err
	}
	vo.ID = acDo.ID
	return nil
}

// GetActivity ...
func GetActivity(id uint) (model.ActivityVO, error) {
	var activity model.ActivityVO
	var acDO model.ActivityDO
	acDO.ID = id
	err := model.GetActivity(&acDO)
	if err != nil {
		return model.ActivityVO{}, err
	}
	activity.ID = acDO.ID
	activity.Title = acDO.Title
	activity.LeaderSay = acDO.LeaderSay
	activity.RouteDesc = acDO.RouteDesc
	activity.RoutePics = acDO.RoutePics
	activity.LeaderID = acDO.LeaderID
	activity.StartTime = acDO.StartTime
	activity.CollectionPlace = acDO.CollectionPlace
	activity.QrCode = acDO.QrCode
	activity.RegistrationDeadline = acDO.RegistrationDeadline
	activity.CurCount = acDO.CurCount
	activity.CountLimit = acDO.CountLimit
	activity.Status = acDO.Status
	switch activity.Status {
	case model.UnderReview:
		activity.StatusDesc = model.UnderReviewDesc
		break
	case model.FailToPassReview:
		activity.StatusDesc = model.FailToPassReviewDesc
		break
	case model.Approved:
		activity.StatusDesc = model.ApprovedDesc
		break
	case model.RegistrationDeadline:
		activity.StatusDesc = model.RegistrationDeadlineDesc
		break
	case model.ActivityEnd:
		activity.StatusDesc = model.ActivityEndDesc
		break
	case model.ActivityCancel:
		activity.StatusDesc = model.ActivityCancelDesc
		break
	}
	// if current time > activity  registration deadline
	currentTime := time.Now().Unix() 
	if currentTime >= acDO.RegistrationDeadline {
		activity.StatusDesc = model.RegistrationDeadlineDesc
	}
	return activity, nil
}

// SearchActivities ...
func SearchActivities(param model.SearchActivitiesParam) (int, []*model.ActivityVO, error) {
	var activities []*model.ActivityVO
	total, acDos, err := model.SearchActivityList(param)
	if err != nil {
		return 0, nil, err
	}
	for _, ac := range acDos {
		useDo, err := QueryUserByID(ac.LeaderID)
		if err != nil {
			log.MainLogger.Error(fmt.Sprintf("QueryUserByID err: %v", err))
		}
		statusDesc := ""
		switch ac.Status {
		case model.UnderReview:
			statusDesc = model.UnderReviewDesc
			break
		case model.FailToPassReview:
			statusDesc = model.FailToPassReviewDesc
			break
		case model.Approved:
			statusDesc = model.ApprovedDesc
			break
		case model.RegistrationDeadline:
			statusDesc = model.RegistrationDeadlineDesc
			break
		case model.ActivityEnd:
			statusDesc = model.ActivityEndDesc
			break
		case model.ActivityCancel:
			statusDesc = model.ActivityCancelDesc
			break
		}

		// if current time > activity  registration deadline
		currentTime := time.Now().Unix() 
		if currentTime >= ac.RegistrationDeadline {
			statusDesc = model.RegistrationDeadlineDesc
		}
		
		activities = append(activities, &model.ActivityVO{
			ID:                   ac.ID,
			Title:                ac.Title,
			LeaderName:           useDo.Nickname,
			Phone:                useDo.Phone,
			LeaderSay:            ac.LeaderSay,
			RouteDesc:            ac.RouteDesc,
			RoutePics:            ac.RoutePics,
			StartTime:            ac.StartTime,
			CollectionPlace:      ac.CollectionPlace,
			QrCode:               ac.QrCode,
			StatusDesc:           statusDesc,
			RegistrationDeadline: ac.RegistrationDeadline,
			CountLimit:           ac.CountLimit,
			CurCount:             ac.CurCount,
			Status:               ac.Status,
		})
	}
	return total, activities, nil
}

// UpdateActivity ...
func UpdateActivity(param model.UpdateActivityParam) error {
	status := model.Unknown
	if param.IsCancel {
		status = model.ActivityEnd
	}
	if status != model.ActivityEnd {
		return model.UpdateActivityDO(&model.ActivityDO{
			ID:                   param.ID,
			Status:               model.UnderReview,
			Title:                param.Activity.Title,
			LeaderSay:            param.Activity.LeaderSay,
			RouteDesc:            param.Activity.RouteDesc,
			RoutePics:            param.Activity.RoutePics,
			StartTime:            param.Activity.StartTime,
			CollectionPlace:      param.Activity.CollectionPlace,
			QrCode:               param.Activity.QrCode,
			RegistrationDeadline: param.Activity.RegistrationDeadline,
			CountLimit:           param.Activity.CountLimit,
		})
	} else {
		return model.UpdateActivityDO(&model.ActivityDO{
			ID:     param.ID,
			Status: status,
		})
	}
}

// VerifyActivity ...
func VerifyActivity(id uint, st int) error {
	return model.UpdateActivityDO(&model.ActivityDO{
		ID:     id,
		Status: st,
	})
}

// RegistrationActivity ...
func RegistrationActivity(userId uint, acId uint) error {
	acDo, err := GetActivity(acId)
	if err != nil {
		return err
	}
	if acDo.CurCount >= acDo.CountLimit {
		return errors.New("人数已满，停止报名。")
	}
	if time.Now().Unix() > acDo.RegistrationDeadline {
		return errors.New("截止时间已到，禁止报名。")
	}
	rss, err := model.GetRegistrationByUIDAndAcID(userId, acId)
	fmt.Printf("RSS %v", rss)
	if len(rss) > 0 {
		err = model.QueryAndUpdateRegistration(userId, acId, model.RegistrationDone)
	} else {
		return model.CreateRegistration(&model.RegistrationDO{
			UserID:     userId,
			ActivityID: acId,
			Status:     model.RegistrationDone,
			CancelTime: time.Now(),
		})
	}
	return nil
}

// GetRegistrationUsers ...
func GetRegistrationUsers(acId uint) ([]*model.RegistrationUserVO, error) {
	rss, err := model.GetRegistrationWithUsers(acId)
	if err != nil {
		return nil, err
	}
	return rss, nil
}

// CancelRegistrationActivity ...
func CancelRegistrationActivity(userId uint, acId uint) error {
	return model.QueryAndUpdateRegistration(userId, acId, model.RegistrationCancel)
}
